import styled from 'styled-components'
import { reduce } from 'lodash'
import React, { useCallback, useEffect, useState } from 'react'
import Controller from '../../component/Controller'
import Header from '../../component/Header'
import { useTranslation } from 'react-i18next'
import Icon from '../../component/Icon'
import Cell from '../../component/Cell'
import { upgrade, upgradeInfo, wallet } from '../../service'
import Message from '../../component/Message'
import { Detector, UpgradeValue, WalletInfo } from '../../service/interface'
import Sheet from '../../component/sheet'
import { CYCLE_UNIT } from '../../constants'
import IconBg from '../../asserts/icon_bg.webp'
import { sigFigs } from '../../utils/number'
import { isIOS } from '../../utils/check'
import Loading from '../../component/Loading'
import gtag from '../../google/analytics'
import { GtagEvent } from '../../google/analytics/Event'

const MAX_LEVEL = 'max'
const UNSUPPORT = 'nothing'

enum AccelerateType {
    Detector = 'detector',
    Charging = 'station',
    Speed = 'speed',
    Bot = 'robot'
}

type ItemType = {
    title: string;
    data: Array<{ key: AccelerateType; title?: string, des: string | { icon: React.ReactNode, text: string }, origin?: any }>
}

type UpgradeItemType = {
    current?: string;
    isMax: boolean;
    isUnsupport: boolean;
    next?: UpgradeValue & { levelNum?: number }
}

type AccelerateData = {
    performance: ItemType,
    upgrade: ItemType
}


const Container = styled(Controller)`
    background-color: ${(prop) => prop.theme.background.normal};
`

const Content = styled.div`
    padding: 0 1rem 0;
    box-sizing: border-box;
`

const Box = styled.div<{ $marginTop?: string }>`
    margin-top:  ${({ $marginTop }) => $marginTop};;
`

const Title = styled.div`
    font-weight: bold;
    font-size: 1rem;
    text-align: start;
    color: ${(prop) => prop.theme.text.normal};
`
const List = styled.div<{ $isVertical?: number }>`
    padding: .875rem 0;
    display: flex;
    flex-direction: ${({ $isVertical }) => $isVertical ? 'column' : 'row'};
    gap: 1rem;
`

const CollectionCell = styled.div`
    padding: .625rem .5rem;
    box-sizing: border-box;
    background-color: ${(prop) => prop.theme.background.box};
    border-radius: .625rem;
    flex: 1;
    display: flex;
    align-items: start;
`

const CollectionCellRight = styled.div`
    margin-left: .375rem;
    .title {
        color: ${(prop) => prop.theme.text.normal};
        font-weight: bold;
        font-size: .75rem;
        text-align: start;
        line-height: 1.4375rem;
    }
    .description {
        font-weight: bold;
        font-size: .625rem;
        color: ${(prop) => prop.theme.text.coin};
        text-align: start;
        display: flex;
        align-items: center;
    }
`

const Text = styled.div<{ $hasIcon: number }>`
    margin-left: ${({ $hasIcon }) => $hasIcon ? '2px' : 0};
`

const CoinIcon = () => {
    return <Icon
        name='icon_coin'
        width='0.75rem'
    />
}

const Accelerate: React.FC = () => {
    const { t } = useTranslation()
    const [loading, setLoading] = useState(false)
    const [data, setData] = useState<AccelerateData>();
    const [info, setInfo] = useState<WalletInfo>();
    const [btcCount, setBtcCount] = useState(0)
    const [showSheet, setShowSheet] = useState(false);
    const [sheetContent, setSheetContent] = useState({ title: '', text: '', tips: '', button: '', disable: false, balance: '', type: '' })

    const fetchBalanceData = useCallback(async () => {
        const info = await wallet()
        if (info.success) {
            if (!info.data) {
                return
            }
            setInfo(info.data)
            setBtcCount(Number(info.data.balance || 0))
        }
    }, [])

    const fetchData = useCallback(async () => {
        setLoading(true)
        const result = await upgradeInfo();
        setLoading(false)
        if (!result.success || !result.data) {
            Message.error(result.message || t('error.none'))
            return;
        }

        const userDetector = result.data.userDetector;
        const map: { [key in AccelerateType]?: keyof Detector } = {
            [AccelerateType.Detector]: 'detLevel',
            [AccelerateType.Speed]: 'speedLevel',
            [AccelerateType.Charging]: 'cycleLevel',
        }

        const obj = reduce(result.data, (draft: { [key in AccelerateType]?: UpgradeItemType }, value, key) => {
            if (Array.isArray(value)) {
                if (key in map) {
                    const idx = Number(userDetector[map[key as AccelerateType]!]);
                    const curData = value[idx - 1];
                    let current = curData?.currValue || '0';
                    const next = {
                        ...value[idx],
                        upgradeCost: curData?.upgradeCost || '0',
                        levelNum: idx + 1
                    };

                    const isMax = MAX_LEVEL === curData?.upgradeCost;
                    const isUnsupport = UNSUPPORT === curData?.upgradeCost;

                    if (key === AccelerateType.Detector && current !== '') {
                        current = sigFigs(current, 4)
                    }

                    if (key === AccelerateType.Speed) {
                        current = Number(current).toFixed(2)
                    }
                    draft[key as AccelerateType] = {
                        isMax,
                        isUnsupport,
                        current,
                        next
                    }
                }
                return draft
            }

            if (typeof value === 'string') {
                draft[key as AccelerateType] = {
                    current: '',
                    isMax: MAX_LEVEL === value,
                    isUnsupport: UNSUPPORT === value,
                    next: {
                        upgradeCost: value,
                        currValue: '',
                        level: ''
                    }
                }
            }
            return draft;

        }, {})

        const list = [
            { key: AccelerateType.Detector, icon: true, text: (s: string) => `+${s}` },
            { key: AccelerateType.Charging, text: (s: string) => `${s}${CYCLE_UNIT}` },
            { key: AccelerateType.Speed, text: (s: string) => `${s}S/1${CYCLE_UNIT}` }
        ];
        const upgradeData = list.map(item => item.key).concat(AccelerateType.Bot)
        const upgradeText = (n?: UpgradeValue) => {
            if (!n) {
                return ''
            }
            let str = n.upgradeCost
            if (n.level) {
                str += `/${n.level} level`
            }
            return str;
        }

        fetchBalanceData()
        setData({
            performance: {
                title: t('accelerate.performance.title'),
                data: list.map(item => ({
                    key: item.key,
                    des: {
                        icon: item.icon ? <CoinIcon /> : undefined,
                        text: item.text(obj[item.key]?.current || '0')
                    }
                }))
            },
            upgrade: {
                title: t('accelerate.upgrades.title'),
                data: upgradeData.map(item => ({
                    key: item,
                    origin: obj[item],
                    des: {
                        icon: obj[item]?.isUnsupport ? undefined : <CoinIcon />,
                        text: obj[item]?.isUnsupport ? '' : upgradeText(obj[item]?.next)
                    }
                }))
            }
        })
    }, [fetchBalanceData, t])

    useEffect(() => {
        try {
            fetchData()
        } catch (error) {
            Message.error(t('error.none'))
        }
    }, [fetchData, t])

    const onCellClick = (key: string, item: UpgradeItemType) => {

        if (item.isUnsupport) {
            Message.info(t('common.stayTuned'))
            return
        }

        if (item.isMax) {
            Message.info(t('accelerate.max'))
            return
        }

        if (!item.next) {
            return
        }

        const balance = Number(item.next.upgradeCost || 0);
        setSheetContent({
            button: t('modal.get'),
            type: key,
            title: t(`modal.upgrade.${key}.title_level`, { level: item.next.levelNum || 0 }),
            text: t(`modal.upgrade.${key}.des`),
            tips: t(`modal.upgrade.${key}.tips_num`, { num: item.next.currValue }),
            balance: item.next.upgradeCost,
            disable: !(balance && (Number(info?.balance) > balance))
        })
        setShowSheet(true);
    }

    const onConfirmClick = async () => {
        if (sheetContent.disable) {
            return
        }
        setShowSheet(false);
        gtag.event(GtagEvent.Upgrade, { type: sheetContent.type })
        const res = await upgrade({ type: sheetContent.type });
        if (!res.success) {
            Message.error(res.message)
            return;
        }

        const msg = sheetContent.type === AccelerateType.Bot ? t('modal.good') : t('modal.upgrade.success')
        Message.success({ position: 'center', element: msg });
        fetchData();
    }

    return <Container
        hiddenSafeBottom={true}
        imagebackground={{
            image: IconBg,
            style: isIOS() ? {} : { position: 'fixed' } // TODO: why absolute will case some gesture problem in andriod
        }}
    >
        <Header
            btcCount={btcCount}
        />
        <Content>
            <Box $marginTop='1.8125rem'>
                <Title>{data?.performance.title || ''}</Title>
                <List>
                    {data?.performance.data.map(item =>
                        <CollectionCell key={item.key}>
                            <Icon
                                name={`accelerate_${item.key}`}
                                width='1.4375rem'
                            />
                            <CollectionCellRight>
                                <div className='title'>{t(`accelerate.performance.${item.key}`)}</div>
                                <div className='description'>
                                    {typeof item.des === 'string' ? <Text $hasIcon={0}>{item.des}</Text> : <>{item.des.icon}<Text $hasIcon={1}>{item.des.text}</Text></>}
                                </div>
                            </CollectionCellRight>
                        </CollectionCell>)}
                </List>
            </Box>
            <Box $marginTop='.625rem'>
                <Title>{data?.upgrade.title || ''}</Title>
                <List $isVertical={1}>
                    {data?.upgrade.data.map(item => <Cell
                        onClick={() => onCellClick(item.key, item.origin)}
                        key={item.key}
                        icon={<Icon
                            name={`accelerate_${item.key}`}
                            width='2.25rem'
                        />}
                        title={<div style={{ fontSize: '0.875rem' }}>{t(`accelerate.upgrades.${item.key}`)}</div>}
                        subTitle={typeof item.des === 'string' ? <Text $hasIcon={0}>{item.des}</Text> : <>{item.des.icon}<Text $hasIcon={1}>{item.des.text}</Text></>}
                        arrow={item.origin?.next ? true : false}
                    />)}
                </List>
            </Box>
        </Content>
        <Sheet
            type='modal'
            upgrade={{
                icons: [{
                    count: sheetContent.balance,
                    icon: true,
                }],
                text: sheetContent.text,
                tips: sheetContent.tips
            }}
            title={sheetContent.title}
            closable={true}
            onClose={() => setShowSheet(false)}
            show={showSheet}
            confirm={{
                key: 'confirm',
                label: sheetContent.button,
                disable: sheetContent.disable,
                onClick: onConfirmClick
            }}
        />
        <Loading show={loading} />
    </Container>
}

export default Accelerate